<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- deployment.qdoc -->
  <title>Deploying QML Applications | Qt 5.12 5.12.3</title>
  <link rel="stylesheet" type="text/css" href="style/offline-simple.css" />
  <script type="text/javascript">
    document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css");
    // loading style sheet breaks anchors that were jumped to before
    // so force jumping to anchor again
    setTimeout(function() {
        var anchor = location.hash;
        // need to jump to different anchor first (e.g. none)
        location.hash = "#";
        setTimeout(function() {
            location.hash = anchor;
        }, 0);
    }, 0);
  </script>
</head>
<body>
<div class="header" id="qtdocheader">
  <div class="main">
    <div class="main-rounded">
      <div class="navigationbar">
        <table><tr>
<td ><a href="index.html">Qt 5.12</a></td><td >Deploying QML Applications</td></tr></table><table class="buildversion"><tr>
<td id="buildversion" width="100%" align="right">Qt 5.12.3 参考指南</td>
        </tr></table>
      </div>
    </div>
<div class="content">
<div class="line">
<div class="content mainContent">
<div class="sidebar">
<div class="toc">
<h3><a name="toc">目录</a></h3>
<ul>
<li class="level1"><a href="#deploying-applications-with-qt-creator">使用Qt Creator部署应用程序</a></li>
<li class="level1"><a href="#qml-caching">QML缓存</a></li>
<li class="level1"><a href="#compiling-qml-ahead-of-time">提前编译QML</a></li>
<li class="level2"><a href="#limitations">限制</a></li>
<li class="level1"><a href="#prototyping-with-qml-scene">QML Scene原型制作</a></li>
<li class="level1"><a href="#initializing-the-qml-runtime-in-applications">在应用程序中初始化QML Runtime</a></li>
<li class="level2"><a href="#initializing-with-qquickview">使用QQuickView初始化</a></li>
<li class="level2"><a href="#creating-a-qqmlengine-directly">直接创建QQmlEngine</a></li>
<li class="level1"><a href="#managing-resource-files-with-the-qt-resource-system">使用Qt资源系统管理资源文件</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">部署QML应用程序</h1>
<span class="subtitle"></span>
<!-- $$$qtquick-deployment.html-description -->
<div class="descr"> <a name="details"></a>
<p>QML文档由QML运行时加载和执行。这包括声明性UI引擎以及内置的QML类型和插件模块，此外还提供了对第三方QML类型和模块的访问。</p>
<p>使用QML的应用程序需要调用QML runtime才能执行QML文档。这可以通过创建<a href="../qtquick/qquickview.html">QQuickView</a> 或 <a href="../qtqml/qqmlengine.html">QQmlEngine</a>来实现，如下所述。此外，声明性UI包包含qmlscene工具，它用于加载<code>.qml</code>文件。这个工具对于开发和测试QML代码非常有用，而不需要编写C++应用程序来加载QML runtime。</p>
<a name="deploying-applications-with-qt-creator"></a>
<h2 id="deploying-applications-with-qt-creator">使用Qt Creator部署应用程序</h2>
<p><a href="http://doc.qt.io/qtcreator/index.html">Qt Creator</a> 将QML应用程序部署并打包到各种平台。对于移动设备，Qt Creator可以直接将应用程序捆绑到各自的平台包格式，如APK。</p>
<p>对于更多信息，请浏览:</p>
<ul>
<li><a href="deployment.html">部署Qt应用程序</a></li>
<li><a href="http://doc.qt.io/qtcreator/creator-running-targets.html">在多个平台上运行</a></li>
<li><a href="http://doc.qt.io/qtcreator/creator-deployment.html">部署到设备</a></li>
</ul>
<p>在目标平台上运行应用程序时，应用程序需要访问QML库的位置。当使用<a href="../qmake/qmake-manual.html">qmake</a>时， <code>QT_INSTALL_QML</code>环境指向库的位置。<a href="http://qt.io/download">Qt安装程序</a> 将QML库安装在 <i>&lt;version&gt;</i><code>/</code><i>&lt;compiler&gt;</i><code>/qml</code>目录中。</p>
<a name="qml-caching"></a>
<h2 id="qml-caching">QML缓存</h2>
<p>QML runtime通过解析和生成字节码来加载QML文档。大多数情况下，文档自上次加载以来没有发生变化。为了加快这个加载过程，QML runtime为每个QML文档维护一个缓存文件。这个缓存文件包含编译后的字节码和QML文档结构的二进制表示。此外，当多个应用程序使用相同的QML文档时，代码所需的内存在应用程序进程之间共享。缓存文件是通过在POSIX兼容的操作系统上的<code>mmap()</code>系统调用加载的，或者在Windows上通过<code>CreateFileMapping()</code>加载的，从而节省了大量内存。</p>
<p>每次加载更改后的QML文档时，都会自动重新创建缓存。缓存文件位于名为&quot;qmlcache&quot;的 <a href="../qtcore/qstandardpaths.html#StandardLocation-enum">QStandardPaths::CacheLocation</a> 的子目录中。文件扩展名为 <code>.qmlc</code>，用于QML文档， <code>.jsc</code> 用于导入的JavaScript模块。</p>
<a name="compiling-qml-ahead-of-time"></a>
<h2 id="compiling-qml-ahead-of-time">提前编译QML</h2>
<p>

将编译的QML文档自动缓存到缓存文件中会显著加快应用程序的加载时间。但是，缓存文件的初始创建仍然需要一些时间，特别是当应用程序第一次启动时。为了避免这一初始步骤并从一开始就提供更快的启动时间，qt的构建系统允许您与应用程序的其余部分同时执行qml文件的编译步骤。 </p>
<p>如果你想使用预先编译好的QML文件部署你的应用程序，那么你必须以特定的方式组织文件和构建系统:</p>
<ul>
<li>所有QML文档(包括JavaScript文件)都必须通过<a href="../qtcore/resources.html">Qt的资源系统</a>作为资源包含进来。</li>
<li>您的应用程序必须通过<code>qrc:///</code>URL方案加载QML文档。</li>
<li>可以使用<code>CONFIG+=qtquickcompiler</code> 指令提前启用编译。</li>
<li>如果您正在使用CMake构建系统，那么您可以将<code>find_package(Qt5QuickCompiler)</code> 调用插入到<code>CMakeLists.txt</code> 中，并用<code>qtquick_compiler_add_resources</code>替换 <code>qt5_add_resources</code>的使用。</li>
</ul>
<p>这种开发和部署应用程序的方法的另一个好处是，您将在应用程序编译时收到QML文档语法错误的通知，而不是在加载文件时收到运行时的通知。</p>
<a name="limitations"></a>
<h3 >限制</h3>
<p>目前，这个特性将把您的应用程序绑定到正在编译的Qt版本，因为它将用编译后的二进制版本替换资源中的QML文档源代码。源文件不再存在。这意味着当对不同版本的Qt使用相同的应用程序而不重新编译它时，加载QML文档将会失败，并带有一条错误消息。</p>
<p>提前编译是通过这种方式实现的，因为该特性源自一个附加组件，用于商业应用程序环境，在商业应用程序环境中不需要部署源代码，通常可以接受在更改Qt时需要重新编译。</p>
<p>我们计划在Qt的未来版本中实现对保留源文档的支持。</p>
<a name="prototyping-with-qml-scene"></a>
<h2 id="prototyping-with-qml-scene">QML Scene原型制作</h2>
<p>声明性UI包包括一个QML运行时工具<a href="qtquick-qmlscene.html">qmlscene</a>，它加载并显示QML文档。在应用程序开发阶段，这对于原型化基于QML的应用程序非常有用，而不需要编写自己的C++应用程序来调用QML运行时。</p>
<a name="initializing-the-qml-runtime-in-applications"></a>
<h2 id="initializing-the-qml-runtime-in-applications">在应用程序中初始化QML Runtime</h2>
<p>要运行使用QML的应用程序，应用程序必须调用QML runtime。这是通过编写Qt C++应用程序来实现的，它可以通过以下方式加载<a href="../qtqml/qqmlengine.html">QQmlEngine</a>:</p>
<ul>
<li>通过<a href="../qtquick/qquickview.html">QQuickView</a> instance, 实例加载QML文件，或者</li>
<li>创建一个<a href="../qtqml/qqmlengine.html">QQmlEngine</a> 实例并用 <a href="../qtqml/qqmlcomponent.html">QQmlComponent</a>加载QML文件</li>
</ul>
<a name="initializing-with-qquickview"></a>
<h3 >使用QQuickView初始化</h3>
<p><a href="../qtquick/qquickview.html">QQuickView</a> 是一个基于<a href="../qtgui/qwindow.html">QWindow</a>类，它能够加载QML文件。例如，如果有一个QML文件，<code>application.qml</code>，它看起来是这样的:</p>
<pre class="qml">

  import QtQuick 2.3

  <span class="type"><a href="../qtquick/qml-qtquick-rectangle.html">Rectangle</a></span> { <span class="name">width</span>: <span class="number">100</span>; <span class="name">height</span>: <span class="number">100</span>; <span class="name">color</span>: <span class="string">&quot;red&quot;</span> }

</pre>
<p>它可以像这样加载到Qt应用程序的<code>main.cpp</code>文件中:</p>
<pre class="cpp">

  <span class="preprocessor">#include &lt;QGuiApplication&gt;</span>
  <span class="preprocessor">#include &lt;QQuickView&gt;</span>

  <span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span> <span class="operator">*</span>argv<span class="operator">[</span><span class="operator">]</span>)
  {
      <span class="type"><a href="../qtgui/qguiapplication.html">QGuiApplication</a></span> app(argc<span class="operator">,</span> argv);

      <span class="type"><a href="../qtquick/qquickview.html">QQuickView</a></span> view;
      view<span class="operator">.</span>setSource(<span class="type"><a href="../qtcore/qurl.html">QUrl</a></span><span class="operator">::</span>fromLocalFile(<span class="string">&quot;application.qml&quot;</span>));
      view<span class="operator">.</span>show();

      <span class="keyword">return</span> app<span class="operator">.</span>exec();
  }

</pre>
<p>这将创建一个基于<a href="../qtgui/qwindow.html">QWindow</a>的视图，该视图显示<code>application.qml</code>的内容。</p>
<p>该应用程序的 <code>.pro</code> <a href="../qmake/qmake-project-files.html">项目文件</a> 必须为<code>QT</code>变量指定<code>declarative（声明）</code> 声明模块。例如:</p>
<pre class="cpp">

  TEMPLATE <span class="operator">+</span><span class="operator">=</span> app
  QT <span class="operator">+</span><span class="operator">=</span> quick
  SOURCES <span class="operator">+</span><span class="operator">=</span> main<span class="operator">.</span>cpp

</pre>
<a name="creating-a-qqmlengine-directly"></a>
<h3 >直接创建QQmlEngine</h3>
<p>如果<code>application.qml</code>没有任何图形组件，或者由于其他原因而倾向于避免<a href="../qtquick/qquickview.html">QQuickView</a> ，则可以直接构造<a href="../qtqml/qqmlengine.html">QQmlEngine</a>在这种情况下， <code>application.qml</code> 将作为一个<a href="../qtqml/qqmlcomponent.html">QQmlComponent</a>实例被加载，而不是被放置到视图中：</p>
<pre class="cpp">

  <span class="preprocessor">#include &lt;QGuiApplication&gt;</span>
  <span class="preprocessor">#include &lt;QQmlEngine&gt;</span>
  <span class="preprocessor">#include &lt;QQmlContext&gt;</span>
  <span class="preprocessor">#include &lt;QQmlComponent&gt;</span>

  <span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span> <span class="operator">*</span>argv<span class="operator">[</span><span class="operator">]</span>)
  {
      <span class="type"><a href="../qtgui/qguiapplication.html">QGuiApplication</a></span> app(argc<span class="operator">,</span> argv);

      <span class="type"><a href="../qtqml/qqmlengine.html">QQmlEngine</a></span> engine;
      <span class="type"><a href="../qtqml/qqmlcontext.html">QQmlContext</a></span> <span class="operator">*</span>objectContext <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="../qtqml/qqmlcontext.html">QQmlContext</a></span>(engine<span class="operator">.</span>rootContext());

      <span class="type"><a href="../qtqml/qqmlcomponent.html">QQmlComponent</a></span> component(<span class="operator">&amp;</span>engine<span class="operator">,</span> <span class="string">&quot;application.qml&quot;</span>);
      <span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>object <span class="operator">=</span> component<span class="operator">.</span>create(objectContext);

      <span class="comment">// ... delete object and objectContext when necessary</span>

      <span class="keyword">return</span> app<span class="operator">.</span>exec();
  }

</pre>
<p>如果您没有使用中 Qt Quick的任何图形项，可以用上面代码中的<a href="../qtcore/qcoreapplication.html">QCoreApplication</a>替换<a href="../qtgui/qguiapplication.html">QGuiApplication</a> 这允许使用QML作为一种语言，而不依赖于<a href="../qtgui/qtgui-index.html">Qt GUI</a> 模块。</p>
<p>有关 <a href="../qtqml/qqmlengine.html">QQmlEngine</a>, <a href="../qtqml/qqmlcontext.html">QQmlContext</a> 和 <a href="../qtqml/qqmlcomponent.html">QQmlComponent</a>的更多信息，以及通过<a href="../qtcore/resources.html">Qt的资源系统</a>包含QML文件的详细信息，请参阅<a href="../qtqml/qtqml-cppintegration-data.html">qtqml-cppintegration-exposecppattributes.html</a>{将C++类型的属性公开给QML} 。</p>
<a name="managing-resource-files-with-the-qt-resource-system"></a>
<h2 id="managing-resource-files-with-the-qt-resource-system">使用Qt资源系统管理资源文件</h2>
<p><a href="../qtcore/resources.html">Qt 资源系统</a>允许将资源文件存储为应用程序可执行文件中的二进制文件。当构建混合QML/C++应用程序时，这可能是有用的，因为它通过资源系统URI方案而不是相对于文件系统资源的相对或绝对路径来引用QML文件（以及诸如图像和声音文件的其他资源）。但是，请注意，如果使用资源系统，则只要更改了qml源文件，就必须重新编译应用程序可执行文件，以便更新包中的资源。</p>
<p>在QML/ C++混合应用程序中使用资源系统:</p>
<ul>
<li>C创建一个<code>.qrc</code> <a href="../qtcore/resources.html">资源集合文件</a> ，该文件以XML格式列出资源文件</li>
<li>在C++中，使用<code>:/</code> 前缀或<code>qrc</code> 模式的URL加载 main QML文件作为资源</li>
</ul>
<p>完成此操作后，QML中由相对路径指定的所有文件将从资源系统加载。资源系统的使用对QML层是完全透明的;这意味着所有QML代码都应该使用相对路径引用资源文件，而<i>不</i>应该使用<code>qrc</code>方案。此方案应该只在C++代码中用于引用资源文件。</p>
<p>下面是一个使用<a href="../qtcore/resources.html">Qt资源系统</a>打包的应用程序。目录结构如下</p>
<pre class="cpp">

  project
      <span class="operator">|</span><span class="operator">-</span> example<span class="operator">.</span>qrc
      <span class="operator">|</span><span class="operator">-</span> main<span class="operator">.</span>qml
      <span class="operator">|</span><span class="operator">-</span> images
          <span class="operator">|</span><span class="operator">-</span> background<span class="operator">.</span>png
      <span class="operator">|</span><span class="operator">-</span> main<span class="operator">.</span>cpp
      <span class="operator">|</span><span class="operator">-</span> project<span class="operator">.</span>pro

</pre>
<p><code>main.qml</code> 和 <code>background.png</code> 文件将打包为资源文件。这是在<code>example.qrc</code>资源集合文件中完成的:</p>
<pre class="cpp">

  &lt;!DOCTYPE RCC&gt;
  &lt;RCC version=&quot;1.0&quot;&gt;

  &lt;qresource prefix=&quot;/&quot;&gt;
      &lt;file&gt;main.qml&lt;/file&gt;
      &lt;file&gt;images/background.png&lt;/file&gt;
  &lt;/qresource&gt;

  &lt;/RCC&gt;

</pre>
<p>由于<code>background.png</code>是一个资源文件，<code>main.qml</code>可以使用<code>example.qrc</code>中指定的相对路径来引用它:</p>
<pre class="qml">

  <span class="comment">// main.qml</span>
  import QtQuick 2.3

  <span class="type"><a href="../qtquick/qml-qtquick-image.html">Image</a></span> { <span class="name">source</span>: <span class="string">&quot;images/background.png&quot;</span> }

</pre>
<p>为了让QML正确定位资源文件， <code>main.cpp</code> 使用<code>qrc</code>方案加载main QML文件<code>main.qml</code>作为资源文件:</p>
<pre class="cpp">

  <span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span> <span class="operator">*</span>argv<span class="operator">[</span><span class="operator">]</span>)
  {
      <span class="type"><a href="../qtwidgets/qapplication.html">QApplication</a></span> app(argc<span class="operator">,</span> argv);

      <span class="type"><a href="../qtquick/qquickview.html">QQuickView</a></span> view;
      view<span class="operator">.</span>setSource(<span class="type"><a href="../qtcore/qurl.html">QUrl</a></span>(<span class="string">&quot;qrc:/main.qml&quot;</span>));
      view<span class="operator">.</span>show();

      <span class="keyword">return</span> app<span class="operator">.</span>exec();
  }

</pre>
<p>最后，<code>project.pro</code> 使用RESOURCES变量表示应该使用<code>example.qrc</code> 构建应用程序资源:</p>
<pre class="cpp">

  QT += qml

  SOURCES += main.cpp
  RESOURCES += example.qrc

</pre>
<p>有关更多信息，请参见<a href="../qtcore/resources.html">Qt资源系统</a>。</p>
</div>
<!-- @@@qtquick-deployment.html -->
        </div>
       </div>
   </div>
   </div>
</div>
<div class="footer">
   <p>
   <acronym title="Copyright">&copy;</acronym> 2019 The Qt Company Ltd.
   Documentation contributions included herein are the copyrights of
   their respective owners.<br/>    The documentation provided herein is licensed under the terms of the    <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation    License version 1.3</a> as published by the Free Software Foundation.<br/>    Qt and respective logos are trademarks of The Qt Company Ltd.     in Finland and/or other countries worldwide. All other trademarks are property
   of their respective owners. </p>
</div>
</body>
</html>
